package com.iothub.netty4.nettypack;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 目前重连还会提示异常
 * 在类前面加上 @ChannelHandler.Sharable 解决重连接问题
 */
@ChannelHandler.Sharable
public class TcpServerHandler extends ChannelInboundHandlerAdapter {

    private final static Logger logger = LoggerFactory.getLogger(TcpServerHandler.class);

    int connectId = 0;
    int offlineId = 0;
    int state = 1;


    public TcpServerHandler() {

    }

    /**
     * 读取数据
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //将客户端传入的消息转换为Netty的ByteBuf类型
        ByteBuf in = (ByteBuf) msg;
        // 在控制台打印传入的消息
        String recvCmds = in.toString(CharsetUtil.UTF_8);

        logger.info("channelRead --> 接收到数据：" + recvCmds);

        SendMsg(ctx,"AT+ACK\r\n");
        //SendMsg(ctx,"recv msg -> " + recvCmds);
    }

    /**
     * 发送消息
     */
    public void SendMsg(ChannelHandlerContext ctx, String msg) {

        /*try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }*/
        ctx.channel().writeAndFlush(Unpooled.copiedBuffer(msg, CharsetUtil.UTF_8));
    }

    /**
     * 客户端连接回调
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        connectId++;
        logger.info("tcp client : " + ctx.channel().remoteAddress().toString());
        SendMsg(ctx,"AT+ACK\r\n");
    }

    /**
     * 客户端主动离线回调
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        offlineId++;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx,Object evt) throws Exception {
        if(evt instanceof IdleStateEvent) {
            IdleStateEvent e = (IdleStateEvent) evt;
            switch(e.state()){
                case READER_IDLE:{
                    logger.error("读时间超时");
                    //RemoteNodeController.removeRemoteNodeInfo(ctx);

                }break;
                case WRITER_IDLE:{
                    logger.error("写时间超时");
                }break;
                case ALL_IDLE:{
                    logger.error("读写时间超时，正在移除设备!");
                    channelInactive(ctx);
                    ctx.channel().close();
                }break;
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //System.out.println("exceptionCaught");
        //打印异常栈跟踪
        //cause.printStackTrace();
        ctx.channel().close();
        // 关闭该Channel
        ctx.close();
        logger.info("exceptionCaught 异常，关闭连接！");
    }
}
